package com.ruoyi.app.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ruoyi.app.domain.AppImGroup;
import com.ruoyi.app.domain.AppImGroupApply;
import com.ruoyi.app.domain.AppUser;
import com.ruoyi.app.domain.bo.AppImGroupBo;
import com.ruoyi.app.domain.vo.AppImGroupVo;
import com.ruoyi.app.domain.vo.AppUserRes;
import com.ruoyi.app.domain.vo.AppUserVo;
import com.ruoyi.app.mapper.AppImGroupApplyMapper;
import com.ruoyi.app.mapper.AppImGroupMapper;
import com.ruoyi.app.mapper.AppUserMapper;
import com.ruoyi.app.service.IAppImGroupService;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.im.core.TxTemplate;
import com.ruoyi.system.domain.UpAppImGroupReq;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 群组Service业务层处理
 *
 * @author ruoyi
 * @date 2025-11-11
 */
@RequiredArgsConstructor
@Service
public class AppImGroupServiceImpl implements IAppImGroupService {

    private final AppImGroupMapper baseMapper;
    private final AppUserMapper appUserMapper;
    private final AppImGroupApplyMapper appImGroupApplyMapper;
    private final TxTemplate txTemplate;

    /**
     * 查询群组
     */
    @Override
    public AppImGroupVo queryById(String id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询群组列表
     */
    @Override
    public TableDataInfo<AppImGroupVo> queryPageList(AppImGroupBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<AppImGroup> lqw = buildQueryWrapper(bo);
        Page<AppImGroupVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询群组列表
     */
    @Override
    public List<AppImGroupVo> queryList(AppImGroupBo bo) {
        LambdaQueryWrapper<AppImGroup> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<AppImGroup> buildQueryWrapper(AppImGroupBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<AppImGroup> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getGroupName()), AppImGroup::getGroupName, bo.getGroupName());
        lqw.eq(StringUtils.isNotBlank(bo.getGroupAvatar()), AppImGroup::getGroupAvatar, bo.getGroupAvatar());
        lqw.eq(bo.getGroupType() != null, AppImGroup::getGroupType, bo.getGroupType());
        lqw.eq(StringUtils.isNotBlank(bo.getOwnerId()), AppImGroup::getOwnerId, bo.getOwnerId());
        lqw.eq(bo.getStatus() != null, AppImGroup::getStatus, bo.getStatus());
        return lqw;
    }

    /**
     * 新增群组
     */
    @Override
    public Boolean insertByBo(AppImGroupBo bo) {
        AppImGroup add = BeanUtil.toBean(bo, AppImGroup.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改群组
     */
    @Override
    public Boolean updateByBo(AppImGroupBo bo) {
        AppImGroup update = BeanUtil.toBean(bo, AppImGroup.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(AppImGroup entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除群组
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public List<AppImGroup> searchGroup(String keyWord) {
        LambdaQueryWrapper<AppImGroup> appImGroupLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (containsChinese(keyWord)){
            appImGroupLambdaQueryWrapper.like(AppImGroup::getGroupName, keyWord);
        }else {
            appImGroupLambdaQueryWrapper.eq(AppImGroup::getId, keyWord);
        }
        appImGroupLambdaQueryWrapper.eq(AppImGroup::getSearchFlag, 0);
        return baseMapper.selectList(appImGroupLambdaQueryWrapper);
    }

    public static boolean containsChinese(String str) {
        return str != null && str.matches(".*[\\u4e00-\\u9fa5].*");
    }


    @Override
    public String setSearchGroupFlag(String groupId, Integer flag) {
        LambdaQueryWrapper<AppImGroup> appImGroupLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appImGroupLambdaQueryWrapper.eq(AppImGroup::getId, groupId);
        AppImGroup appImGroup = baseMapper.selectOne(appImGroupLambdaQueryWrapper);
        if (appImGroup != null){
            appImGroup.setSearchFlag(flag);
            baseMapper.updateById(appImGroup);
        }
        return "success";
    }

    @Override
    public Object selGroupById(String groupId) {
        LambdaQueryWrapper<AppImGroup> appImGroupLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appImGroupLambdaQueryWrapper.eq(AppImGroup::getId, groupId);
        return baseMapper.selectOne(appImGroupLambdaQueryWrapper);
    }

    @Override
    public Object updateGroupData(UpAppImGroupReq req) {
        LambdaQueryWrapper<AppImGroup> appImGroupLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appImGroupLambdaQueryWrapper.eq(AppImGroup::getId, req.getId());
        AppImGroup appImGroup = baseMapper.selectOne(appImGroupLambdaQueryWrapper);
        if (appImGroup != null){
            BeanUtil.copyProperties(req, appImGroup);
            baseMapper.updateById(appImGroup);
        }
        return R.ok();
    }

    @Override
    public Object selTongGroup(Long userId, Long targetId) {
        //查询所有群聊
        List<AppImGroup> appImGroups = baseMapper.selectList();
        List<AppImGroup> res = new ArrayList<>();
        if (CollUtil.isNotEmpty(appImGroups)){
            for (AppImGroup appImGroup : appImGroups) {
                String member = appImGroup.getMember();
                List<Long> memberList = JSONUtil.toList(member, Long.class);
                if (memberList.contains(userId) && memberList.contains(targetId)){
                    res.add(appImGroup);
                }
            }
        }
        return R.ok(res);
    }

    @Override
    public Object addGroupMember(String groupId, List<Long> userIdList) {
        LambdaQueryWrapper<AppImGroup> appImGroupLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appImGroupLambdaQueryWrapper.eq(AppImGroup::getId, groupId);
        AppImGroup appImGroup = baseMapper.selectOne(appImGroupLambdaQueryWrapper);
        if (appImGroup != null){
            String member = appImGroup.getMember();
            List<Long> memberList = JSONUtil.toList(member, Long.class);
            memberList.addAll(userIdList);
            //去重
            memberList = memberList.stream().distinct().collect(Collectors.toList());
            appImGroup.setMember(JSONUtil.toJsonStr(memberList));
            baseMapper.updateById(appImGroup);
        }
        return R.ok();
    }

    @Override
    public Object addGroupManager(String groupId, List<Long> userIdList) {
        LambdaQueryWrapper<AppImGroup> appImGroupLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appImGroupLambdaQueryWrapper.eq(AppImGroup::getId, groupId);
        AppImGroup appImGroup = baseMapper.selectOne(appImGroupLambdaQueryWrapper);
        if (appImGroup != null){
            String manager = appImGroup.getManager();
            List<Long> managerList = new ArrayList<>();
            if (manager!=null){
                managerList = JSONUtil.toList(manager, Long.class);
            }
            managerList.addAll(userIdList);
            appImGroup.setManager(JSONUtil.toJsonStr(managerList));
            int i = baseMapper.updateById(appImGroup);
            //转为字符串集合
            List<String> userIdListStr = userIdList.stream().map(String::valueOf).collect(Collectors.toList());
            txTemplate.addGroupAdmin(groupId, userIdListStr);
        }

        return R.ok();
    }

    @Override
    public Object getGroupManagerData(String groupId) {
        LambdaQueryWrapper<AppImGroup> appImGroupLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appImGroupLambdaQueryWrapper.eq(AppImGroup::getId, groupId);
        AppImGroup appImGroup = baseMapper.selectOne(appImGroupLambdaQueryWrapper);
        List<AppUserRes> appUserRes = new ArrayList<>();
        if (appImGroup != null){
            String manager = appImGroup.getManager();
            List<Long> managerList = JSONUtil.toList(manager, Long.class);
            if (CollUtil.isEmpty(managerList)){
                return R.ok(appUserRes);
            }
            LambdaQueryWrapper<AppUser> appUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
            appUserLambdaQueryWrapper.in(AppUser::getId, managerList);
            List<AppUser> appUsers = appUserMapper.selectList(appUserLambdaQueryWrapper);
            for (AppUser appUser : appUsers) {
                AppUserRes appUserRes1 = new AppUserRes();
                appUserRes1.setUserId(appUser.getId());
                appUserRes1.setUserName(appUser.getNickName());
                appUserRes1.setAvatar(appUser.getAvatar());
                appUserRes.add(appUserRes1);
            }
            return R.ok(appUserRes);
        }
        return R.ok(appUserRes);
    }

    @Override
    public Object removeGroupMember(String groupId, List<Long> userIdList) {
        //移除
        LambdaQueryWrapper<AppImGroup> appImGroupLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appImGroupLambdaQueryWrapper.eq(AppImGroup::getId, groupId);
        AppImGroup appImGroup = baseMapper.selectOne(appImGroupLambdaQueryWrapper);
        if (appImGroup != null){
            String member = appImGroup.getMember();
            List<Long> memberList = JSONUtil.toList(member, Long.class);
            memberList.removeAll(userIdList);
            appImGroup.setMember(JSONUtil.toJsonStr(memberList));
            baseMapper.updateById(appImGroup);
            //调用im 移除群成员
            //转成String集合
            List<String> userIdListStr = userIdList.stream().map(String::valueOf).collect(Collectors.toList());
            txTemplate.removeUserGroup(appImGroup.getId(),userIdListStr);
        }
        return R.ok();
    }

    @Override
    public Object delGroup(String groupId) {
        LambdaQueryWrapper<AppImGroup> appImGroupLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appImGroupLambdaQueryWrapper.eq(AppImGroup::getId, groupId);
        //如果不是群主 无法删除
        AppImGroup appImGroup = baseMapper.selectOne(appImGroupLambdaQueryWrapper);
        if (appImGroup!=null){
            if (!appImGroup.getOwnerId().equals(LoginHelper.getUserId().toString())){
                return R.fail("非群主无法删除");
            }
            int delete = baseMapper.delete(appImGroupLambdaQueryWrapper);
            if (delete>0){
                txTemplate.destroyGroup(groupId);
            }
            return R.ok();
        }
        return R.ok();
    }

    @Override
    public Object silenceGroupMember(String groupId, List<Long> userIdList) {
        LambdaQueryWrapper<AppImGroup> appImGroupLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appImGroupLambdaQueryWrapper.eq(AppImGroup::getId, groupId);
        AppImGroup appImGroup = baseMapper.selectOne(appImGroupLambdaQueryWrapper);
        if (appImGroup != null){
            List<Long> silenceMemberList = new ArrayList<>();
            String silenceMember = appImGroup.getSilenceMember();
            if (silenceMember!=null){
                silenceMemberList = JSONUtil.toList(silenceMember, Long.class);
                silenceMemberList.addAll(userIdList);

            }
            if (silenceMember==null){
                silenceMemberList = userIdList;
            }
            silenceMember = JSONUtil.toJsonStr(silenceMemberList);
            appImGroup.setSilenceMember(silenceMember);
            baseMapper.updateById(appImGroup);
            //调用im 禁言群成员
            //转成String集合
            List<String> userIdListStr = userIdList.stream().map(String::valueOf).collect(Collectors.toList());
            txTemplate.forbidUserGroup(appImGroup.getId(),userIdListStr,60*60*24);

        }
        return R.ok();
    }

    @Override
    public Object removeSilenceGroupMember(String groupId, List<Long> userIdList) {
        LambdaQueryWrapper<AppImGroup> appImGroupLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appImGroupLambdaQueryWrapper.eq(AppImGroup::getId, groupId);
        AppImGroup appImGroup = baseMapper.selectOne(appImGroupLambdaQueryWrapper);
        if (appImGroup != null){
            String silenceMember = appImGroup.getSilenceMember();
            if (silenceMember!=null && !"1".equals(silenceMember)){
                List<Long> silenceMemberList = JSONUtil.toList(silenceMember, Long.class);
                silenceMemberList.removeAll(userIdList);
                silenceMember = JSONUtil.toJsonStr(silenceMemberList);
                appImGroup.setSilenceMember(silenceMember);
                int i = baseMapper.updateById(appImGroup);
                //调用im 禁言群成员
                //转成String集合
                List<String> userIdListStr = userIdList.stream().map(String::valueOf).collect(Collectors.toList());
                txTemplate.forbidUserGroup(appImGroup.getId(),userIdListStr,0);
            }
        }
        return R.ok();
    }

    @Override
    public Object silenceAllGroupMember(String groupId) {
        LambdaQueryWrapper<AppImGroup> appImGroupLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appImGroupLambdaQueryWrapper.eq(AppImGroup::getId, groupId);
        AppImGroup appImGroup = baseMapper.selectOne(appImGroupLambdaQueryWrapper);
        if (appImGroup != null){
            appImGroup.setSilenceMember("1");
            baseMapper.updateById(appImGroup);
            //调用im 禁言群成员
            txTemplate.forbidUserGroup(appImGroup.getId(),null,60*60*24);
        }
        return R.ok();
    }

    @Override
    public Object ignoreGroupApply(List<Long> ids) {
        LambdaUpdateWrapper<AppImGroupApply> appImGroupApplyLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        appImGroupApplyLambdaUpdateWrapper.in(AppImGroupApply::getId, ids);
        appImGroupApplyMapper.delete(appImGroupApplyLambdaUpdateWrapper);
        return R.ok();
    }

    @Override
    public Object cancelGroupManager(String groupId, List<Long> userIdList) {
        LambdaQueryWrapper<AppImGroup> appImGroupLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appImGroupLambdaQueryWrapper.eq(AppImGroup::getId, groupId);
        AppImGroup appImGroup = baseMapper.selectOne(appImGroupLambdaQueryWrapper);
        if (appImGroup != null){
            String manager = appImGroup.getManager();
            List<Long> managerList = JSONUtil.toList(manager, Long.class);
            managerList.removeAll(userIdList);
            manager = JSONUtil.toJsonStr(managerList);
            appImGroup.setManager(manager);
            baseMapper.updateById(appImGroup);
            //转为String集合
            List<String> userIdListStr = userIdList.stream().map(String::valueOf).collect(Collectors.toList());
            txTemplate.removeGroupAdmin(appImGroup.getId(),userIdListStr);
        }

        return R.ok();
    }

    @Override
    public Object silenceGroupList(String groupId) {
        LambdaQueryWrapper<AppImGroup> appImGroupLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appImGroupLambdaQueryWrapper.eq(AppImGroup::getId, groupId);
        AppImGroup appImGroup = baseMapper.selectOne(appImGroupLambdaQueryWrapper);
        List<AppUserRes> res = new ArrayList<>();
        if (appImGroup != null){
            String silenceMember = appImGroup.getSilenceMember();
            if (silenceMember!=null && !"1".equals(silenceMember)){
                List<Long> list = JSONUtil.toList(silenceMember, Long.class);
                if (CollUtil.isEmpty(list)){
                    return res;
                }
                LambdaQueryWrapper<AppUser> appUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
                appUserLambdaQueryWrapper.in(AppUser::getId,list);
                List<AppUser> appUsers = appUserMapper.selectList(appUserLambdaQueryWrapper);
                for (AppUser appUser : appUsers) {
                    AppUserRes appUserRes = new AppUserRes();
                    appUserRes.setUserId(appUser.getId());
                    appUserRes.setUserName(appUser.getNickName());
                    appUserRes.setAvatar(appUser.getAvatar());
                    res.add(appUserRes);
                }
                return res;
            }
        }
        return res;
    }

    @Override
    public Object cancelSilenceAllGroupMember(String groupId) {
        LambdaQueryWrapper<AppImGroup> appImGroupLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appImGroupLambdaQueryWrapper.eq(AppImGroup::getId, groupId);
        AppImGroup appImGroup = baseMapper.selectOne(appImGroupLambdaQueryWrapper);
        if (appImGroup != null){
            baseMapper.update(
                    null,
                    new LambdaUpdateWrapper<AppImGroup>()
                            .eq(AppImGroup::getId, appImGroup.getId())
                            .set(AppImGroup::getSilenceMember, null)
            );
            //调用im 禁言群成员
//            txTemplate.unForbidAllUser(appImGroup.getId());
        }
        return null;
    }
}
